import requests
import time, datetime
import os, sys
import multiprocessing as mp
from bs4 import BeautifulSoup

ServiceKey = 'wUhbq/9OQDrudjkNWRXEtRsi831Z3MTe89qOGbvQi8M='
lastlist = [170100, 179999, 185416, 204999, 209999, 214999, 209999, 214999, 219999]


class BlockedUserError(Exception):
	def __init__(self):
		super().__init__('Service key is blocked')


def check_to_skip(appnumber, year):
	try:
		f = open('D:\\KIPRIS\\Biblio\\{}\\{}.xml'.format(year, appnumber), 'r', encoding="utf-8")
		xml = f.read()
		soup = BeautifulSoup(xml, 'xml')
		if soup.find("resultMsg").text=="NORMAL SERVICE.":
			return 1
		else:
			return 0
	except FileNotFoundError:
		return 0


def downloader(ind, year):
	digit = len(str(ind))
	appnumber = "10"+ str(year) + "0"*(7-digit) + str(ind)
	url = "http://plus.kipris.or.kr/kipo-api/kipi/patUtiModInfoSearchSevice/getBibliographyDetailInfoSearch?applicationNumber={}&ServiceKey={}".format(appnumber, ServiceKey)
	# Checking whether we may skip the appnumber
	if check_to_skip(appnumber, year) == 1:
		print("{} is already downloaded.".format(appnumber))
	else:
		# Request session
		start = time.time()
		while True:
			try:
				response = requests.get(url, timeout = 60)
				break
			except requests.exceptions.Timeout:
				print("Request {} tmied out - going to sleep for 60 secs - {}".format(appnumber, datetime.datetime.now()))
				time.sleep(60)
				pass
			except requests.exceptions.ConnectionError:
				print("ConnectionError for requst {} - retry".format(appnumber))
				pass
			except:
				print("Unknown Error for request {} - retry".format(appnumber))
				pass
		A = time.time() - start
		if A < 0.35:
			time.sleep(0.35 - A)
		data = response.text
		# Detecting BlockedUserError 
		soup = BeautifulSoup(data, 'xml')
		try:
			if soup.find("resultMsg").text == "Blocked users.":
				raise BlockedUserError
			pass
		except Exception as e:
			print(e)
			print(datetime.datetime.now())
			sys.exit()
		# Saving the response
		with open('D:\\KIPRIS\\Biblio\\{}\\{}.xml'.format(year, appnumber), 'w', encoding="utf-8") as f:
			f.write(data)
		n = os.path.getsize('D:\\KIPRIS\\Biblio\\{}\\{}.xml'.format(year, appnumber))
		size = round(n / 1024.0, 1)
		A = round(A, 3)
		print(str(appnumber)+ ' - ' + str(response.status_code)+ ' - ' +str(A) +'sec - ' +str(size) + 'KB')


def by_year(year):
	try:
		os.mkdir('D:\\KIPRIS\\Biblio\\{}'.format(year))
	except:
		pass
	last = lastlist[year-2010]
	indlist = range(1, last+1)
	for ind in indlist:
		downloader(ind, year)


if __name__ == '__main__':
	pool = mp.Pool(9)
	pool.map(by_year, range(2010, 2018))